package cn.sciento.farm.devicemanager.gateway.uplink.service.sensor;

import cn.sciento.farm.devicemanager.common.constant.DeviceConstant;
import cn.sciento.farm.devicemanager.common.exception.NullDeviceTypeException;
import cn.sciento.farm.devicemanager.common.util.NumberUtil;
import cn.sciento.farm.devicemanager.dao.entity.DevCollectionType;
import cn.sciento.farm.devicemanager.gateway.lorawan.config.JwtManager;
import cn.sciento.farm.devicemanager.gateway.model.uplink.CollectionData;
import cn.sciento.farm.devicemanager.gateway.model.uplink.ControlData;
import cn.sciento.farm.devicemanager.service.CollectionTypeService;
import com.alibaba.fastjson.JSON;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.messaging.core.BeanFactoryMessageChannelDestinationResolver;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * @author wumu
 * @version V1.0
 * @date 4/11/18
 * @time 11:14 AM
 */
@Service
public class DatabaseContextTransferService implements ContextTransferService {

    private Logger logger = LoggerFactory.getLogger(getClass());

    @Autowired
    CollectionTypeService collectionTypeService;

    @Override
    public List<CollectionData> regularData(String concentrator, String n, String data) {
        List<CollectionData> deviceDataList = new ArrayList<CollectionData>();
        Map<String, Object> map = (Map<String, Object>) JSON.parse(data);
        String node = "" + map.get("id");
        if (StringUtils.isEmpty(node)) {
            return deviceDataList;
        }
        map.remove("id");

        for (Map.Entry entry : map.entrySet()) {
            String circuit = (String) entry.getKey();
            int value = ((Number) entry.getValue()).intValue();
            DevCollectionType devCollectionType = collectionTypeService.getById(circuit);
            if(devCollectionType == null){
                throw new NullPointerException("没有相关的采集类型"+circuit);
            }
            CollectionData jDeviceData = new CollectionData();
            jDeviceData.setEui(concentrator);
            jDeviceData.setNode(node);
            jDeviceData.setCircuit(circuit);
            jDeviceData.setData(computeRealValue(devCollectionType, circuit, value));
            jDeviceData.setName(devCollectionType.getName());
            jDeviceData.setProtocol(DeviceConstant.SIMPLE);
            jDeviceData.setType(circuit);
            deviceDataList.add(jDeviceData);
        }
        return deviceDataList;
    }

    private float computeRealValue(DevCollectionType devCollectionType, String circuit, Object value) {
        int originValue = ((Number) value).intValue();
        double realValue = originValue*1.0/ devCollectionType.getProportion();

        if (devCollectionType == null) {
            logger.warn("没有相关的采集类型：" + circuit);
            throw new NullDeviceTypeException("没有相关设备类型");
        }
        // 执行表达式
        return NumberUtil.double2float(realValue, 2);
    }

    @Override
    public List<ControlData> regularSwitch(String concentrator, String n, String data) {
        List<ControlData> switchStatusList = new ArrayList<ControlData>();
        Map<String, Object> map = (Map<String, Object>) JSON.parse(data);
        String node = "" + map.get("id");
        if (StringUtils.isEmpty(node)) {
            return switchStatusList;
        }
        String key = "";
        for (String s : map.keySet()) {
            if(s.startsWith("L")){
                key = s;
                break;
            }
        }
        byte[] dist = null;
        byte[] wfb = null;
        for (Map.Entry entry : map.entrySet()) {
            byte[] origin = NumberUtil.getBitArray((Integer) entry.getValue());
            String strkey = (String) entry.getKey();
            if (strkey.startsWith("L")) {
                key = strkey;
                dist = switchParse(strkey, origin);
            } else if(strkey.equals("wFB")){
                wfb = switchParse(key, origin);
            }
            origin = null;
        }
        if (dist == null && wfb == null ) {
            return switchStatusList;
        }
        int length = dist.length;
        for (int i = length - 1; i >= 0; i--) {
            ControlData jSwitchStatus = new ControlData();
            jSwitchStatus.setEui(concentrator);
            jSwitchStatus.setNode(node);
            jSwitchStatus.setCircuit(String.valueOf(length - i));
            jSwitchStatus.setEn(dist[i]);
            if (wfb != null) {
                jSwitchStatus.setDeviceType(DeviceConstant.FLOW_CONTROL_TYPE);
                jSwitchStatus.setWaterFeedback(wfb[i]);
            } else {
                jSwitchStatus.setDeviceType(DeviceConstant.DEVICE_TYPE_LIGHT);
            }
            jSwitchStatus.setType(DeviceConstant.SIMPLE);
            switchStatusList.add(jSwitchStatus);
        }
        return switchStatusList;
    }

    private byte[] switchParse (String switchType, byte[] origin){
        byte[] dist = null;
        switch (switchType) {
            case DeviceConstant.SWITCH_TYPE_4:
                dist = Arrays.copyOfRange(origin, 28, 32);
                break;
            case DeviceConstant.SWITCH_TYPE_8:
                dist = Arrays.copyOfRange(origin, 24, 32);
                break;
            case DeviceConstant.SWITCH_TYPE_12:
                dist = Arrays.copyOfRange(origin, 20, 32);
                break;
            case DeviceConstant.SWITCH_TYPE_16:
                dist = Arrays.copyOfRange(origin, 16, 32);
                break;
            default:
        }
        return dist;
    }
}
